package com.leeyu.rabbitmq.confirms;

import com.leeyu.rabbitmq.util.RabbitMQConnectionUtil;
import com.rabbitmq.client.*;
import org.junit.Test;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class Publisher {

    private static final String QUEUE_NAME = "confirms-queue";

    @Test
    public void publish() throws Exception {

        // 获取连接
        Connection connection = RabbitMQConnectionUtil.getConnection();

        // 构建channel
        Channel channel = connection.createChannel();

        // 构建队列 durable设置为true，保证RabbitMQ重启后队列还存在
        // 队列的持久化保证
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);

        // 开启confirms机制，保证消息发送到交换机
        channel.confirmSelect();

        // 设置confirms的异步回调
        // 保证消息成功发送到交换机或失败都会进行回调
        channel.addConfirmListener(new ConfirmListener() {

            /* 消息成功发送到交换机回调 */
            @Override
            public void handleAck(long l, boolean b) throws IOException {
                System.out.println("消息成功发送到Exchange！");
            }

            /* 消息发送到交换机失败回调 */
            @Override
            public void handleNack(long l, boolean b) throws IOException {
                System.out.println("消息发送到Exchange失败，请重试！");
            }
        });

        // 通过basicPublish方法中的mandatory参数设置为true开启
        // 保证消息进入队列失败后会回调
        channel.addReturnListener(new ReturnListener() {
            @Override
            public void handleReturn(int i, String s, String s1, String s2, AMQP.BasicProperties basicProperties, byte[] bytes) throws IOException {
                System.out.println("消息成功送达" + QUEUE_NAME + "队列!");
            }
        });

        // 设置队列持久化，Queue默认不做持久化，需要手动设置
        // 保证队列持久化消息不丢失（队列中消息的持久化保证）
        // 配合durable保证队列和消息的持久化
        AMQP.BasicProperties props = new AMQP.BasicProperties()
                .builder()
                .deliveryMode(2)
                .build();

        // 发布消息 mandatory设置为true开启消息达到队列后确认机制
        channel.basicPublish("", QUEUE_NAME, true, props, "Hello Rabbit!".getBytes(StandardCharsets.UTF_8));

        System.out.println("消息发送成功！");
    }
}
